﻿using System;
using System.Collections.Generic;
using System.Text;

namespace HippoScript
{
    /// <summary>
    /// 脚本上下文
    /// </summary>
    [Serializable]
    public class ScriptContext
    {
        //非脚本的对象
        private Dictionary<string, object> _fieldValue;//字段-值
        private Dictionary<string, string> _fieldDeclar;//字段-声明
        private List<string> _codeModule;
        private List<string> _referencedAssemblies;
        private List<string> _usingStatment;
        private Boolean _isRefreshFieldValue;
        /// <summary>
        /// 创建默认字段的上下文
        /// </summary>
        public ScriptContext()
        {
            _fieldValue = new Dictionary<string, object>();
            _fieldDeclar=new Dictionary<string, string>();
            _referencedAssemblies=new List<string>();
            _usingStatment = new List<string>();
            _codeModule = new List<string>();
            _isRefreshFieldValue = true;
        }

        /// <summary>
        /// 累加上下文信息
        /// </summary>
        /// <param name="context"></param>
        public void Append(ScriptContext context)
        {
            CollectionsExtension.Append(_fieldValue, context._fieldValue);
            CollectionsExtension.Append(_codeModule, context._codeModule);
            CollectionsExtension.Append(_referencedAssemblies, context._referencedAssemblies);
            CollectionsExtension.Append(_usingStatment, context._usingStatment);
            _isRefreshFieldValue = context._isRefreshFieldValue;
        }
             
        /// <summary>
        /// 方法+字段定义代码模块
        /// </summary>
        public List<string> CodeModule
        {
            get { return _codeModule; }
        }
	
        public List<string> RefAssemblies
        {
            get { return _referencedAssemblies; }
           
        }

        public List<string> Usings
        {
            get { return _usingStatment; }

        }
        /// <summary>
        /// 计算后对象中字段值是否刷回Field
        /// 默认为true
        /// </summary>
        public Boolean IsRefreshFieldValue
        {
            get { return _isRefreshFieldValue; }
            set { _isRefreshFieldValue = value; }
        }
        /// <summary>
        /// 加入Using语句
        /// </summary>
        /// <param name="usingStr"></param>
        public void AddUsing(string usingStr)
        {
            if (!_usingStatment.Contains(usingStr))
            {
                _usingStatment.Add(usingStr);
            }
            
        }

        /// <summary>
        /// 加入程序集引用，如 System.dll
        /// </summary>
        /// <param name="assmblyStr"></param>
        public void AddReferencedAssembly(string assmblyStr)
        {
            if (!_referencedAssemblies.Contains(assmblyStr))
            {
                _referencedAssemblies.Add(assmblyStr);
            }
        }

        /// <summary>
        /// 加入代码(仅包含方法和变量的定义)
        /// </summary>
        /// <param name="assmblyStr"></param>
        public void AddCode(string code)
        {
            if (!_codeModule.Contains(code))
            {
                _codeModule.Add(code);
            }
        }

        /// <summary>
        /// 加入非脚本对象
        /// </summary>
        /// <param name="name">字段名称</param>
        /// <param name="obj">值</param>
        public void AddObject(string name, object obj)
        {
            _fieldDeclar.Add(name, obj.GetType().ToString());
            _fieldValue.Add(name, obj);
        }

        /// <summary>
        /// 为字段赋值
        /// </summary>
        /// <param name="name">字段名称</param>
        /// <param name="obj">值</param>
        public void SetFieldValue(string name, object obj)
        {
            if (_fieldDeclar.ContainsKey(name))
            {
                if (_fieldValue.ContainsKey(name))
                {
                    _fieldValue[name] = obj;
                }
                else
                {
                    _fieldValue.Add(name, obj);
                }
            }
            else
            {
                throw new Exception("No declar field name '" + name + "'");
            }
            
        }

        /// <summary>
        /// 添加字段声明
        /// </summary>
        /// <param name="name">字段名称</param>
        /// <param name="type">字段类型</param>
        public void AddFieldDeclar(string name,string type)
        {
            _fieldDeclar.Add(name, type);
        }

        /// <summary>
        /// 判断是否有计算过的同名值
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public bool IsEvaledObject(string name)
        {
            return _fieldValue.ContainsKey(name);
        }

       /// <summary>
       /// 取得已经保存的object值
       /// </summary>
       /// <param name="name"></param>
       /// <returns></returns>
        public object GetEvaledObject(string name)
        {
            return _fieldValue[name];
        }

        /// <summary>
        /// 取得字段-值集合
        /// </summary>
        public Dictionary<string, object> FieldValue
        {
            get { return _fieldValue; }
        }

        /// <summary>
        /// 取得字段-声明集合
        /// </summary>
        public Dictionary<string, string> FieldDeclar
        {
            get { return _fieldDeclar; }
        }
    }
}
